package gui;

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;

import messages.JobRequestResult;
import model.Job;
import model.Park;
import model.User;
import controller.Controller;

/**
 * A form to fill out to submit a new Job request. This should only be shown to park managers.
 * 
 * @author James Gunter - jpgunter
 *
 */
public class JobForm extends JPanel implements ActionListener{
  private static final int PREFFERED_WIDTH = 420;
  private static final int PREFERRED_HEIGHT = 380;
  private JTextField my_title_field;
  private JTextField my_description_field;
  private JTextField my_light_n_field;
  private JTextField my_light_d_field;
  private JTextField my_med_n_field;
  private JTextField my_med_d_field;
  private JTextField my_heavy_n_field;
  private JTextField my_heavy_d_field;
  private JButton my_cancel_button;
  private JButton my_submit_button;
  private MainWindow my_parent;
  private Controller my_controller;
  private User my_park_manager;
  private JComboBox my_park_select;
  private JComboBox my_month_select;
  private JComboBox my_day_select;
  private JComboBox my_year_select;
  private JComboBox my_duration_select;

  /**
   * Create the panel.
   */
  public JobForm(MainWindow the_parent, Controller the_controller, User the_park_manager) {
    
    my_parent = the_parent;
    my_controller = the_controller;
    my_park_manager = the_park_manager;
    
    setPreferredSize(new Dimension(PREFFERED_WIDTH, PREFERRED_HEIGHT));
    setLayout(new GridLayout(0, 2, 5,5));
    
    JLabel my_park_label = new JLabel("Park:");
    add(my_park_label);
    
    my_park_select = new JComboBox();
    List<Park> pm_parks = my_controller.getParks(my_park_manager);
    String[] park_names = new String[pm_parks.size()];
    for(int i=0;i<pm_parks.size();i++){
      park_names[i] = pm_parks.get(i).getName();
    }
    my_park_select.setModel(new DefaultComboBoxModel(park_names));
    add(my_park_select);
    
    
    JLabel my_title_label = new JLabel("Title:");
    add(my_title_label);
    
    my_title_field = new JTextField();
    add(my_title_field);
    my_title_field.setColumns(10);
    
    JLabel my_description_label = new JLabel("Description:");
    add(my_description_label);
    
    my_description_field = new JTextField();
    add(my_description_field);
    my_description_field.setColumns(10);
    
    JLabel my_date_label = new JLabel("Date:");
    add(my_date_label);
    
    JPanel panel = new JPanel();
    FlowLayout flowLayout = (FlowLayout) panel.getLayout();
    flowLayout.setAlignment(FlowLayout.LEFT);
    flowLayout.setVgap(0);
    flowLayout.setHgap(0);
    add(panel);
    
    my_month_select = new JComboBox();
    my_month_select.setModel(new DefaultComboBoxModel(new String[] {"Month", "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12"}));
    my_month_select.addActionListener(this);
    panel.add(my_month_select);
    
    my_day_select = new JComboBox();
    my_day_select.setModel(new DefaultComboBoxModel(new String[] {"Day"}));
    panel.add(my_day_select);
    
    my_year_select = new JComboBox();
    String[] years = new String[4];
    years[0] = "Year";
    years[1] = "" + ((new Date()).getYear() + 1900);
    years[2] = "" + ((new Date()).getYear() + 1901);
    years[3] = "" + ((new Date()).getYear() + 1902);
    my_year_select.setModel(new DefaultComboBoxModel(years));
    panel.add(my_year_select);
    
    JLabel my_duration_label = new JLabel("Duration");
    add(my_duration_label);
    
    JPanel panel_1 = new JPanel();
    FlowLayout flowLayout_1 = (FlowLayout) panel_1.getLayout();
    flowLayout_1.setVgap(0);
    flowLayout_1.setHgap(0);
    flowLayout_1.setAlignment(FlowLayout.LEFT);
    add(panel_1);
    
    my_duration_select = new JComboBox();
    my_duration_select.setModel(new DefaultComboBoxModel(new String[] {"1", "2"}));
    panel_1.add(my_duration_select);
    
    JLabel my_light_n_label = new JLabel("Light Workers Needed:");
    add(my_light_n_label);
    
    my_light_n_field = new JTextField();
    add(my_light_n_field);
    my_light_n_field.setColumns(10);
    
    JLabel my_light_d_label = new JLabel("Light Work Description:");
    add(my_light_d_label);
    
    my_light_d_field = new JTextField();
    add(my_light_d_field);
    my_light_d_field.setColumns(10);
    
    JLabel my_med_n_label = new JLabel("Medium Workers Needed:");
    add(my_med_n_label);
    
    my_med_n_field = new JTextField();
    add(my_med_n_field);
    my_med_n_field.setColumns(10);
    
    JLabel my_med_d_label = new JLabel("Medium Work Description:");
    add(my_med_d_label);
    
    my_med_d_field = new JTextField();
    add(my_med_d_field);
    my_med_d_field.setColumns(10);
    
    JLabel my_heavy_n_label = new JLabel("Heavy Workers Needed:");
    add(my_heavy_n_label);
    
    my_heavy_n_field = new JTextField();
    add(my_heavy_n_field);
    my_heavy_n_field.setColumns(10);
    
    JLabel my_heavy_d_label = new JLabel("Heavy Work Description:");
    add(my_heavy_d_label);
    
    my_heavy_d_field = new JTextField();
    add(my_heavy_d_field);
    my_heavy_d_field.setColumns(10);
    
    my_cancel_button = new JButton("Cancel");
    my_cancel_button.addActionListener(this);
    add(my_cancel_button);
    
    my_submit_button = new JButton("Submit");
    my_submit_button.addActionListener(this);
    add(my_submit_button);

  }
  
  /**
   * Gets the friendly message of why the Job failed.
   * @param the_job_request_result - The reason the job request failed to submit.
   */
  private String getFriendlyMessage(JobRequestResult the_job_requst_result){
    String message = "";
    switch(the_job_requst_result) { 
    case DATE_BEYOND_LIMIT:
      message = "The date selected is beyond the maximum future scheduling limit.";
      break;
    case EXCEEDS_MAX_DURATION:
      message = "The duration selected is longer the maximum.";
      break;
    case JOB_IN_PAST:
      message = "The date selected is in the past. You may only submit requests for Jobs in the future.";
      break;
    case MAX_JOBS_REACHED:
      message = "The maximum amount of pending jobs has been reached. Please wait for a job to be completed before submitting your request.";
      break;
    case MAX_WEEKLY_REACHED:
      message = "The maximum amount of pending jobs for that week has been reached. Please wait for a job to be completed before submitting your request.";
      break;
    case WRONG_PARK_MGR:
      message = "You are not allowed to submit requests for this park. How did you even ask it to?";
      break;
    }
    return message;
  }
  
  /**
   * Listener for the buttons on the panel.
   */
  @Override
  public void actionPerformed(ActionEvent the_event) {
    if(the_event.getSource() == my_cancel_button){
      my_parent.back();
    } else if(the_event.getSource() == my_submit_button){
      trySubmitRequest();
    } else if(the_event.getSource() == my_month_select){
      setDays();
    }
    
  }
  
  /**
   * Adds the correct number of day options to the day selection drop-down based on the user-selected month.
   */
  private void setDays() {
    int parsed_month = Integer.parseInt((String)my_month_select.getSelectedItem());
    int days = 1;
    switch(parsed_month){
      case 1:
      case 3:
      case 5:
      case 7:
      case 8:
      case 10:
      case 12:
        days = 31;
        break;
      case 4:
      case 6:
      case 9:
      case 11:
        days = 30;
        break;
      case 2:
        days = 29;
    }
    
    String[] day_list = new String[days+1];
    day_list[0] = "Day";
    for(int i = 1; i <= days; i++)
      day_list[i] = ""+ i;
    
    my_day_select.setModel(new DefaultComboBoxModel(day_list));
  }
  
  /**
   * Try to submit the job request and handle any failures.
   */
  private void trySubmitRequest() {
    if(check_inputs()){
      Job job = new Job();
      job.setTitle(my_title_field.getText());
      job.setDescription(my_description_field.getText());
      job.setPark(my_controller.getPark((String) my_park_select.getSelectedItem()));
      
      int parsed_year = Integer.parseInt((String)(my_year_select.getSelectedItem()));
      int parsed_month = Integer.parseInt((String)(my_month_select.getSelectedItem()));
      int parsed_day = Integer.parseInt((String)(my_day_select.getSelectedItem()));
      job.setDate(new Date(parsed_year - 1900, parsed_month - 1, parsed_day));
      
      int parsed_duration = Integer.parseInt((String)my_duration_select.getSelectedItem());
      job.setDuration(parsed_duration);
      
      int parsed_light_n = Integer.parseInt((String)my_light_n_field.getText());
      int parsed_med_n = Integer.parseInt((String)my_med_n_field.getText());
      int parsed_heavy_n = Integer.parseInt((String)my_heavy_n_field.getText());
      job.setLightWorkNeeded(parsed_light_n);
      job.setLtWorkDesc(my_light_d_field.getText());
      job.setMediumWorkNeeded(parsed_med_n);
      job.setMdWorkDesc(my_med_d_field.getText());
      job.setHeavyWorkNeeded(parsed_heavy_n);
      job.setHvWorkDesc(my_heavy_d_field.getText());
      
      JobRequestResult result = my_controller.submitJobRequest(job, my_park_manager);
      if(result == JobRequestResult.SUCCESS){
        JOptionPane.showMessageDialog(this, "Job Successfully submitted.");
        my_parent.home();
      } else {
        JOptionPane.showMessageDialog(this, getFriendlyMessage(result));
      }
    }
  }
  
  /**
   * Check all the inputs for valid data.
   * @return Whether the inputs passed all validity checks.
   */
  private boolean check_inputs(){
    boolean result = true;
    
    try{
      Calendar cal = Calendar.getInstance();
      int parsed_year = Integer.parseInt((String)(my_year_select.getSelectedItem()));
      int parsed_month = Integer.parseInt((String)(my_month_select.getSelectedItem()));
      int parsed_day = Integer.parseInt((String)(my_day_select.getSelectedItem()));
      Date date = new Date(parsed_year - 1900, parsed_month - 1, parsed_day);
      
      cal.setTime(date);
    } catch(Exception date_exception){
      result = false;
      JOptionPane.showMessageDialog(this, "Invalid Date");
    }
    
    try{
      int num = Integer.parseInt(my_light_n_field.getText());
    } catch(NumberFormatException num_format_exception){
      result = false;
      JOptionPane.showMessageDialog(this, "Number of light workers not a valid number");
    }
    try{
      int num = Integer.parseInt(my_med_n_field.getText());
    } catch(NumberFormatException num_format_exception){
      result = false;
      JOptionPane.showMessageDialog(this, "Number of medium workers not a valid number");
    }
    try{
      int num = Integer.parseInt(my_heavy_n_field.getText());
    } catch(NumberFormatException num_format_exception){
      result = false;
      JOptionPane.showMessageDialog(this, "Number of heavy workers not a valid number");
    }
    
    if(my_title_field.getText().equals("")){
      result = false;
      JOptionPane.showMessageDialog(this, "Please enter a title.");
    }
    if(my_description_field.getText().equals("")){
      result = false;
      JOptionPane.showMessageDialog(this, "Please enter a description.");
    }
    if(my_light_d_field.getText().equals("")){
      result = false;
      JOptionPane.showMessageDialog(this, "Please enter a light work description.");
    }
    if(my_med_d_field.getText().equals("")){
      result = false;
      JOptionPane.showMessageDialog(this, "Please enter a medium work description.");
    }
    if(my_heavy_d_field.getText().equals("")){
      result = false;
      JOptionPane.showMessageDialog(this, "Please enter a heavy work description.");
    }
    return result;
  }
}
